home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / ncurses-5.3 / ncurses / base / lib_addstr.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-27  |  7.1 KB  |  254 lines

  1. /****************************************************************************
  2.  * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
  3.  *                                                                          *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  5.  * copy of this software and associated documentation files (the            *
  6.  * "Software"), to deal in the Software without restriction, including      *
  7.  * without limitation the rights to use, copy, modify, merge, publish,      *
  8.  * distribute, distribute with modifications, sublicense, and/or sell       *
  9.  * copies of the Software, and to permit persons to whom the Software is    *
  10.  * furnished to do so, subject to the following conditions:                 *
  11.  *                                                                          *
  12.  * The above copyright notice and this permission notice shall be included  *
  13.  * in all copies or substantial portions of the Software.                   *
  14.  *                                                                          *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  16.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  18.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  21.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  22.  *                                                                          *
  23.  * Except as contained in this notice, the name(s) of the above copyright   *
  24.  * holders shall not be used in advertising or otherwise to promote the     *
  25.  * sale, use or other dealings in this Software without prior written       *
  26.  * authorization.                                                           *
  27.  ****************************************************************************/
  28.  
  29. /****************************************************************************
  30.  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  31.  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  32.  ****************************************************************************/
  33.  
  34. /*
  35. **    lib_addstr.c
  36. *
  37. **    The routines waddnstr(), waddchnstr().
  38. **
  39. */
  40.  
  41. #include <curses.priv.h>
  42.  
  43. MODULE_ID("$Id: lib_addstr.c,v 1.34 2002/10/06 00:25:25 tom Exp $")
  44.  
  45. #if USE_WIDEC_SUPPORT
  46. #define CONV_DATA   mbstate_t state; wchar_t cached; int clen = 0
  47. #define CONV_INIT   memset (&state, '\0', sizeof (state)); cached = (wchar_t)WEOF
  48. #define NEXT_CHAR(s,ch, n)                        \
  49.     {                                    \
  50.     int len, i = 0;                            \
  51.     memset(&ch, 0, sizeof(cchar_t));                \
  52.     if (cached != (wchar_t) WEOF) {                    \
  53.         ch.chars[i++] = cached;                    \
  54.         cached = (wchar_t) WEOF;                    \
  55.         n -= clen;                            \
  56.         s += clen;                            \
  57.     }                                \
  58.     for (; i < CCHARW_MAX && n > 0; ++i) {                \
  59.         if ((len = mbrtowc(&ch.chars[i], s, n, &state)) < 0) {    \
  60.         code = ERR;                        \
  61.         break;                            \
  62.         }                                \
  63.         if (i == 0 || wcwidth(ch.chars[i]) == 0) {            \
  64.         n -= len;                        \
  65.         s += len;                        \
  66.         } else {                            \
  67.         cached = ch.chars[i];                    \
  68.         clen = len;                        \
  69.         ch.chars[i] = L'\0';                    \
  70.         break;                            \
  71.         }                                \
  72.     }                                \
  73.     if (code == ERR)                        \
  74.         break;                            \
  75.     }
  76. #else
  77. #define CONV_DATA
  78. #define CONV_INIT
  79. #define NEXT_CHAR(s,ch, n)                        \
  80.     ch = *s++;                                \
  81.     --n
  82. #endif
  83.  
  84. NCURSES_EXPORT(int)
  85. waddnstr(WINDOW *win, const char *astr, int n)
  86. {
  87.     unsigned const char *str = (unsigned const char *) astr;
  88.     int code = ERR;
  89.     CONV_DATA;
  90.  
  91.     T((T_CALLED("waddnstr(%p,%s,%d)"), win, _nc_visbufn(astr, n), n));
  92.  
  93.     if (win && (str != 0)) {
  94.     TR(TRACE_VIRTPUT | TRACE_ATTRS, ("... current %s", _traceattr(win->_attrs)));
  95.     code = OK;
  96.     if (n < 0)
  97.         n = (int) strlen(astr);
  98.  
  99.     TR(TRACE_VIRTPUT, ("str is not null, length = %d", n));
  100.     CONV_INIT;
  101.     while ((n > 0) && (*str != '\0')) {
  102.         NCURSES_CH_T ch;
  103.         TR(TRACE_VIRTPUT, ("*str = %#x", *str));
  104.         NEXT_CHAR(str, ch, n);
  105.         if (_nc_waddch_nosync(win, ch) == ERR) {
  106.         code = ERR;
  107.         break;
  108.         }
  109.     }
  110.     _nc_synchook(win);
  111.     }
  112.     TR(TRACE_VIRTPUT, ("waddnstr returns %d", code));
  113.     returnCode(code);
  114. }
  115.  
  116. NCURSES_EXPORT(int)
  117. waddchnstr(WINDOW *win, const chtype * astr, int n)
  118. {
  119.     NCURSES_SIZE_T y = win->_cury;
  120.     NCURSES_SIZE_T x = win->_curx;
  121.     int code = OK;
  122.     struct ldat *line;
  123.  
  124.     T((T_CALLED("waddchnstr(%p,%p,%d)"), win, astr, n));
  125.  
  126.     if (!win)
  127.     returnCode(ERR);
  128.  
  129.     if (n < 0) {
  130.     const chtype *str;
  131.     n = 0;
  132.     for (str = (const chtype *) astr; *str != 0; str++)
  133.         n++;
  134.     }
  135.     if (n > win->_maxx - x + 1)
  136.     n = win->_maxx - x + 1;
  137.     if (n == 0)
  138.     returnCode(code);
  139.  
  140.     line = &(win->_line[y]);
  141. #if USE_WIDEC_SUPPORT
  142.     {
  143.     int i;
  144.     for (i = 0; i < n; ++i)
  145.         SetChar(line->text[i + x], ChCharOf(astr[i]), ChAttrOf(astr[i]));
  146.     }
  147. #else
  148.     memcpy(line->text + x, astr, n * sizeof(*astr));
  149. #endif
  150.     CHANGED_RANGE(line, x, x + n - 1);
  151.  
  152.     _nc_synchook(win);
  153.     returnCode(code);
  154. }
  155.  
  156. #if USE_WIDEC_SUPPORT
  157.  
  158. int
  159. _nc_wchstrlen(const cchar_t * s)
  160. {
  161.     int result = 0;
  162.     while (CharOf(s[result]) != L'\0') {
  163.     result++;
  164.     }
  165.     return result;
  166. }
  167.  
  168. NCURSES_EXPORT(int)
  169. wadd_wchnstr(WINDOW *win, const cchar_t * const astr, int n)
  170. {
  171.     NCURSES_SIZE_T y = win->_cury;
  172.     NCURSES_SIZE_T x = win->_curx;
  173.     int code = OK;
  174.     struct ldat *line;
  175.     int i, start, end;
  176.  
  177.     T((T_CALLED("wadd_wchnstr(%p,%s,%d)"), win, _nc_viscbuf(astr, n), n));
  178.  
  179.     if (!win)
  180.     returnCode(ERR);
  181.  
  182.     if (n < 0) {
  183.     n = _nc_wchstrlen(astr);
  184.     }
  185.     if (n > win->_maxx - x + 1)
  186.     n = win->_maxx - x + 1;
  187.     if (n == 0)
  188.     returnCode(code);
  189.  
  190.     line = &(win->_line[y]);
  191.     start = x;
  192.     end = x + n - 1;
  193.     if (isnac(line->text[x])) {
  194.     line->text[x - 1] = win->_nc_bkgd;
  195.     --start;
  196.     }
  197.     for (i = 0; i < n && x <= win->_maxx; ++i) {
  198.     line->text[x++] = astr[i];
  199.     if (wcwidth(CharOf(astr[i])) > 1) {
  200.         if (x <= win->_maxx)
  201.         AddAttr(line->text[x++], WA_NAC);
  202.         else
  203.         line->text[x - 1] = win->_nc_bkgd;
  204.     }
  205.     }
  206.     if (x <= win->_maxx && isnac(line->text[x])) {
  207.     line->text[x] = win->_nc_bkgd;
  208.     ++end;
  209.     }
  210.     CHANGED_RANGE(line, start, end);
  211.  
  212.     _nc_synchook(win);
  213.     returnCode(code);
  214. }
  215.  
  216. NCURSES_EXPORT(int)
  217. waddnwstr(WINDOW *win, const wchar_t * str, int n)
  218. {
  219.     int code = ERR;
  220.     int i;
  221.  
  222.     T((T_CALLED("waddnwstr(%p,%s,%d)"), win, _nc_viswbufn(str,n), n));
  223.  
  224.     if (win && (str != 0)) {
  225.     TR(TRACE_VIRTPUT | TRACE_ATTRS, ("... current %s", _traceattr(win->_attrs)));
  226.     code = OK;
  227.     if (n < 0)
  228.         n = (int) wcslen(str);
  229.  
  230.     TR(TRACE_VIRTPUT, ("str is not null, length = %d", n));
  231.     while ((n-- > 0) && (*str != L('\0'))) {
  232.         NCURSES_CH_T ch;
  233.         TR(TRACE_VIRTPUT, ("*str[0] = %#lx", *str));
  234.         SetChar(ch, *str++, A_NORMAL);
  235.         i = 1;
  236.         while (i < CCHARW_MAX && n > 0 && (*str != L('\0'))
  237.            && wcwidth(*str) == 0) {
  238.         TR(TRACE_VIRTPUT, ("*str[%d] = %#lx", i, *str));
  239.         ch.chars[i++] = *str++;
  240.         --n;
  241.         }
  242.         if (_nc_waddch_nosync(win, ch) == ERR) {
  243.         code = ERR;
  244.         break;
  245.         }
  246.     }
  247.     _nc_synchook(win);
  248.     }
  249.     TR(TRACE_VIRTPUT, ("waddnwstr returns %d", code));
  250.     returnCode(code);
  251. }
  252.  
  253. #endif
  254.